
# We've got to mock a beanstalkd server.

module Beanstalk
  class TestJob
    attr_reader :ttr, :body

    def initialize(connection, name, body, ttr)
      @connection = connection
      @name = name
      @body = body
      @ttr = ttr
    end

    def delete
      @connection.disturb!

      @connection.queues[@name].shift
    end
  end

  class Pool
    @@connections = []

    # Multiple pool servers are currently not implemented for testing purposes.

    def self.new(server)
      @connection = @@connections.detect { |connection| connection.server == server }

      if @connection
        @connection.up! if @connection.disconnected?

        return @connection
      end

      unless @connection
        @connection = TestConnection.new(server)

        @@connections.push @connection
      end

      @connection
    end

    def self.clear!
      @@connections = []
    end
  end

  class TestConnection
    attr_reader :server

    def initialize(server)
      @server = server

      @availability = :available
      @delay = 0

      @watches = []

      @queues = {}
    end

    def disturb!
      raise Beanstalk::NotConnected unless available?

      sleep @delay
    end

    def delay=(delay)
      @delay = delay
    end

    def use(name)
      disturb!

      @current = name
    end

    def put(data, pri = 65536, delay = 0, ttr = 120)
      disturb!

      @queues[@current] ||= []
      @queues[@current].push [data, pri, delay, ttr]
    end

    def watch(name)
      disturb!

      @watches.push name
    end

    def queues
      @queues
    end

    def up!
      @availability = :available
    end

    def available?
      @availability == :available
    end

    def disconnect!
      @availability = :disconnected
    end

    def disconnected?
      @availability == :disconnected
    end

    def down!
      @availability = :down
    end

    def down?
      @availability == :down
    end

    def reserve
      disturb!

      @watches.each do |name|
        if @queues[name] && !@queues[name].empty?
          data, pri, delay, ttr = @queues[name].first

          return TestJob.new(self, name, data, ttr)
        end
      end

      nil
    end
  end
end

